package com.meetingshow.commu.uiservice;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.validation.groups.Default;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import weibo4j.Status;
import weibo4j.User;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.AccessToken;

import com.meetingshow.common.base.service.model.QueryResults;
import com.meetingshow.common.base.uiservice.BaseUIServiceImp;
import com.meetingshow.common.base.uiservice.exception.BaseUIServiceException;
import com.meetingshow.common.validator.RemoveValidator;
import com.meetingshow.common.validator.UpdateValidator;
import com.meetingshow.commu.dao.model.AnswerPO;
import com.meetingshow.commu.dao.model.QuestionPO;
import com.meetingshow.commu.service.IAnswerService;
import com.meetingshow.commu.service.IQuestionService;
import com.meetingshow.commu.service.model.AnswerQueryParas;
import com.meetingshow.commu.uiservice.model.AnswerQueryParasVO;
import com.meetingshow.commu.uiservice.model.AnswerVO;
import com.meetingshow.meeting.dao.model.TopicPO;
import com.meetingshow.meeting.service.ITopicService;
import com.meetingshow.privilege.dao.model.UserPO;
import com.meetingshow.privilege.service.IUserService;
import com.meetingshow.utils.BaseUtil;
import com.meetingshow.weibo.dao.model.WeiboPO;
import com.meetingshow.weibo.service.IWeiboService;
import com.meetingshow.weibo.service.model.WeiboQueryParas;

public class UIAnswerServiceImp extends BaseUIServiceImp implements
        IUIAnswerService {

    public final static Logger logger = Logger
            .getLogger(UIAnswerServiceImp.class);

    private IAnswerService answerService;
    private IQuestionService questionService;
    private IUserService userService;
    private IWeiboService weiboService;
    private ITopicService topicService;

    /**
     * @return the answerService
     */
    public IAnswerService getAnswerService() {
        return answerService;
    }

    /**
     * @param answerService
     *            the answerService to set
     */
    public void setAnswerService(IAnswerService answerService) {
        this.answerService = answerService;
    }

    public IQuestionService getQuestionService() {
        return questionService;
    }

    public void setQuestionService(IQuestionService questionService) {
        this.questionService = questionService;
    }
    
    public IUserService getUserService() {
        return userService;
    }

    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    public IWeiboService getWeiboService() {
        return weiboService;
    }

    public void setWeiboService(IWeiboService weiboService) {
        this.weiboService = weiboService;
    }
    
    public ITopicService getTopicService() {
        return topicService;
    }

    public void setTopicService(ITopicService topicService) {
        this.topicService = topicService;
    }

    @Override
    public Integer saveAnswer(AnswerVO answerVO) throws BaseUIServiceException {

        if (!BaseUtil.objectNotNull(answerVO)) {
            this.throwValidaterException("answerVO is null.");
        }
        
        if (answerVO.getQuestion() == null
                || answerVO.getQuestion().getQuestionId() == null) {
            this.throwValidaterException("questionId is null.");
        }

        answerVO.setCreateTime(new Date());
        
        validateThrowEx(answerVO);
        
        //验证问题是否存在
        QuestionPO questionPO = validateQuestionExist(answerVO);
        
        AnswerPO answerPO = answerVO.toAnswerPO();
        answerPO.setQuestion(questionPO);
        answerPO.setTopicId(questionPO.getTopicId());
        answerPO.setTopicName(questionPO.getTopicName());

        //验证回答者是否存在
        validateUserExist(answerVO.getFromUserId(), "FromUser");
        
        //验证被回答者是否存在
        validateUserExist(answerVO.getToUserId(), "ToUser");
        
        try {
            Integer answerId = getAnswerService().saveAnswer(answerPO);
            answerVO.setAnswerId(answerId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        //发微博
        Status status = sendStatus(answerPO, questionPO);
        if (status != null) {
            answerPO.setStatusId(String.valueOf(status.getId()));
            try {
                getAnswerService().updateAnswer(answerPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }

        return answerVO.getAnswerId();
    }

    @Override
    public void updateAnswer(AnswerVO answerVO) throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(answerVO)) {
            this.throwValidaterException("answerVO is null.");
        }

        validateThrowEx(answerVO, Default.class, UpdateValidator.class);

        AnswerQueryParas answerQueryParas = new AnswerQueryParas();
        answerQueryParas.setAnswerId_e(String.valueOf(answerVO.getAnswerId()));

        QueryResults<AnswerPO> answerQueryResults = null;
        try {
            answerQueryResults = getAnswerService().queryAnswer(
                    answerQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }

        if (QueryResults.resultsListNotNull(answerQueryResults)) {
            AnswerPO persistAnswerPO = answerQueryResults.getResultList()
                    .get(0);
            persistAnswerPO.setContent(answerVO.getContent());

            try {
                getAnswerService().updateAnswer(persistAnswerPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
    }

    @Override
    public void removeAnswer(AnswerVO answerVO) throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(answerVO)) {
            this.throwValidaterException("answerVO is null.");
        }

        validateThrowEx(answerVO, RemoveValidator.class);

        AnswerQueryParas answerQueryParas = new AnswerQueryParas();
        answerQueryParas.setAnswerId_e(String.valueOf(answerVO.getAnswerId()));

        QueryResults<AnswerPO> answerQueryResults = null;
        try {
            answerQueryResults = getAnswerService().queryAnswer(
                    answerQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }

        if (QueryResults.resultsListNotNull(answerQueryResults)) {
            AnswerPO persistAnswerPO = answerQueryResults.getResultList()
                    .get(0);
            try {
                getAnswerService().removeAnswer(persistAnswerPO);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                throw new BaseUIServiceException(e);
            }
        }
    }
    
    @Override
    public AnswerVO loadAnswerById(Integer answerId)
            throws BaseUIServiceException {
        if (answerId == null)
            this.throwValidaterException("answerId is null.");
        
        AnswerPO answerPO = null;
        try {
            answerPO = getAnswerService().loadAnswerById(answerId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (answerPO == null)
            return null;
        else
            return new AnswerVO(answerPO);
    }

    @Override
    public QueryResults<AnswerVO> queryAnswer(
            AnswerQueryParasVO answerQueryParasVO)
            throws BaseUIServiceException {
        if (!BaseUtil.objectNotNull(answerQueryParasVO)) {
            this.throwValidaterException("answerQueryParasVO is null.");
        }

        validateThrowEx(answerQueryParasVO);

        QueryResults<AnswerPO> answerPOQueryResults = null;
        try {
            answerPOQueryResults = getAnswerService().queryAnswer(
                    answerQueryParasVO.toAnswerQueryParas());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }

        QueryResults<AnswerVO> answerVOQueryResults = new QueryResults<AnswerVO>();
        List<AnswerVO> answerVOList = new ArrayList<AnswerVO>();
        if (QueryResults.resultsListNotNull(answerPOQueryResults)) {
            for (AnswerPO answerPO : answerPOQueryResults.getResultList()) {
                if (BaseUtil.objectNotNull(answerPO)) {
                    answerVOList.add(new AnswerVO(answerPO));
                }
            }
        }

        answerVOQueryResults.setFirstResultNo(answerPOQueryResults
                .getFirstResultNo());
        answerVOQueryResults.setResultsPerGroup(answerPOQueryResults
                .getResultsPerGroup());
        answerVOQueryResults.setResultList(answerVOList);
        answerVOQueryResults.setTotalResultsNum(answerPOQueryResults
                .getTotalResultsNum());

        return answerVOQueryResults;
    }

    /**
     * 验证问题是否存在
     * @param answerVO
     * @return
     * @throws BaseUIServiceException
     */
    private QuestionPO validateQuestionExist(AnswerVO answerVO) throws BaseUIServiceException {
        QuestionPO questionPO = null;
        try {
            questionPO = getQuestionService().loadQuestionById(answerVO.getQuestion().getQuestionId());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        return questionPO;
    }
    
    /**
     * 验证用户是否存在
     * @param userId
     * @param validateName
     * @return
     * @throws BaseUIServiceException
     */
    private UserPO validateUserExist(Integer userId, String validateName) throws BaseUIServiceException {
        UserPO userPO = null;
        try {
            userPO = getUserService().loadUserById(userId);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new BaseUIServiceException(e);
        }
        
        if (userPO == null)
            throw new BaseUIServiceException(validateName + " does not exist.");
        else
            return userPO;
    }
    
    /**
     * 把回答发送到微博
     * @return
     */
    private Status sendStatus(AnswerPO answerPO, QuestionPO questionPO) {
        TopicPO topicPO = null;
        try {
            topicPO = getTopicService().loadTopicById(questionPO.getTopicId());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
        
        String toWeiboName = null;
        if (StringUtils.isBlank(answerPO.getToWeiboName())) {
            // 查询被回答人的微博信息
            WeiboPO toWeiboPO = getWeiboByUserId(String.valueOf(answerPO.getToUserId()));
            Weibo weibo = new Weibo();
            try {
                User user = weibo.showUser(toWeiboPO.getWeiboId());
                toWeiboName = user.getScreenName();
            } catch (WeiboException e) {
                logger.error(e.getMessage(), e);
            }
        } else {
            toWeiboName = answerPO.getToWeiboName();
        }

        StringBuilder weiboContent = new StringBuilder();
        weiboContent
                .append("#")
                .append(topicPO.getMeeting().getName())
                .append(" ")
                .append(topicPO.getTopicName())
                .append("#")
                .append(StringUtils.isNotBlank(toWeiboName) ? "@" + toWeiboName
                        + " " : "").append(answerPO.getContent());

        WeiboPO weiboPO = getWeiboByUserId(String.valueOf(answerPO.getFromUserId()));
        Weibo weibo = new Weibo();
        AccessToken accessToken = new AccessToken(weiboPO.getAccessToken(),
                weiboPO.getAccessTokenSecret());
        weibo.setOAuthAccessToken(accessToken);
        try {
            Status status = weibo.updateStatus(weiboContent.toString());
            return status;
        } catch (WeiboException e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }
    
    private WeiboPO getWeiboByUserId(String userId) {
        WeiboQueryParas weiboQueryParas = new WeiboQueryParas();
        weiboQueryParas.setUserId_e(String.valueOf(userId));
        QueryResults<WeiboPO> wbQueryResults = null;
        try {
            wbQueryResults = getWeiboService().queryWeibo(weiboQueryParas);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        if (!QueryResults.resultsListNotNull(wbQueryResults)) {
            return null;
        } else {
            return wbQueryResults.getResultList().get(0);
        }
    }
}
